#!/usr/bin/env python3
"""
ESP32 自动编译和刷写工具
整合PlatformIO编译和esptool刷写功能
"""

import os
import sys
import subprocess
import time

def run_command(cmd, description="", cwd=None):
    """执行命令并显示结果"""
    print(f"🔄 {description}")
    print(f"💻 执行: {cmd}")
    
    try:
        result = subprocess.run(
            cmd, shell=True, capture_output=True, text=True, cwd=cwd
        )
        if result.returncode == 0:
            print(f"✅ 成功: {description}")
            if result.stdout.strip():
                print(f"📤 输出:\n{result.stdout}")
            return True
        else:
            print(f"❌ 失败: {description}")
            if result.stderr.strip():
                print(f"⚠️ 错误:\n{result.stderr}")
            if result.stdout.strip():
                print(f"📤 输出:\n{result.stdout}")
            return False
    except Exception as e:
        print(f"❌ 执行失败: {e}")
        return False

def check_prerequisites():
    """检查必要的工具和环境"""
    print("🔍 检查开发环境...")
    
    # 检查虚拟环境
    venv_python = "/home/mobox/hardware/esp_venv/bin/python3"
    if not os.path.exists(venv_python):
        print("❌ 虚拟环境不存在")
        return False
    
    # 检查PlatformIO项目
    pio_ini = "/home/mobox/hardware/esp32_platformio/platformio.ini"
    if not os.path.exists(pio_ini):
        print("❌ PlatformIO项目不存在")
        return False
    
    # 检查源代码
    main_cpp = "/home/mobox/hardware/esp32_platformio/src/main.cpp"
    if not os.path.exists(main_cpp):
        print("❌ 源代码文件不存在")
        return False
    
    print("✅ 开发环境检查通过")
    return True

def compile_firmware():
    """编译ESP32固件"""
    print("🔨 编译ESP32固件...")
    
    # 激活虚拟环境并编译
    cmd = "source /home/mobox/hardware/esp_venv/bin/activate && pio run"
    return run_command(
        cmd, 
        "编译ESP32固件", 
        cwd="/home/mobox/hardware/esp32_platformio"
    )

def flash_firmware(erase_first=True):
    """刷写固件到ESP32"""
    firmware_path = "/home/mobox/hardware/esp32_platformio/.pio/build/esp32dev/firmware.bin"
    
    if not os.path.exists(firmware_path):
        print(f"❌ 编译后的固件文件不存在: {firmware_path}")
        return False
    
    # 激活虚拟环境
    os.environ["PATH"] = "/home/mobox/hardware/esp_venv/bin:" + os.environ.get("PATH", "")
    
    # 擦除Flash (可选)
    if erase_first:
        cmd = "esptool.py --port /dev/ttyUSB0 erase_flash"
        if not run_command(cmd, "擦除ESP32 Flash"):
            return False
    
    # 刷写固件
    cmd = f"esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash 0x1000 {firmware_path}"
    return run_command(cmd, "刷写固件到ESP32")

def test_communication():
    """测试ESP32通信"""
    print("📡 测试ESP32通信...")
    
    # 等待ESP32启动
    time.sleep(2)
    
    # 使用测试脚本
    cmd = "cd /home/mobox/hardware/rk3588_controller && timeout 10 python3 -c \"\
import serial; \
import time; \
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=2); \
time.sleep(1); \
ser.write(b'PING\\n'); \
response = ser.readline().decode().strip(); \
ser.close(); \
print('ESP32响应:', response); \
exit(0 if 'OK:PONG' in response else 1)\""
    
    return run_command(cmd, "测试ESP32通信")

def main():
    print("=== ESP32 自动编译刷写工具 ===")
    
    # 检查环境
    if not check_prerequisites():
        print("❌ 环境检查失败，请先设置开发环境")
        return 1
    
    # 编译固件
    print("\n📦 开始编译过程...")
    if not compile_firmware():
        print("❌ 固件编译失败")
        return 1
    
    # 刷写固件
    print("\n📤 开始刷写过程...")
    if not flash_firmware(erase_first=True):
        print("❌ 固件刷写失败")
        return 1
    
    # 测试通信
    print("\n🧪 开始通信测试...")
    if not test_communication():
        print("⚠️ 通信测试失败，但固件已刷写成功")
        print("💡 可以手动运行串口测试: cd rk3588_controller && python3 serial_test.py")
    else:
        print("✅ 通信测试成功!")
    
    print("\n🎉 ESP32固件编译刷写完成!")
    print("📋 下一步:")
    print("   1. 运行主控程序: cd rk3588_controller && python3 main.py")
    print("   2. 或串口测试: cd rk3588_controller && python3 serial_test.py")
    
    return 0

if __name__ == "__main__":
    sys.exit(main()) 